package gek.uni.aspirant.ocl.prolog.generator.generator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Generalization;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.UMLPackage;

public class PrologGenerator {
	private Model model;

	public PrologGenerator(Model model0) {
		this.model = model0;
	}

	public void setModel(Model model0) {
		this.model = model0;
	}

	public Collection<String> generateGeneralizationTreeFacts() {
		// Получаем коллекцию классов из UML модели.
		Collection<String> result = new ArrayList<String>();
		Collection<Class> allClass = getAllClass(model);
		Iterator<Class> allClassIter = allClass.iterator();
		// Достаем Generalization из всех классов.
		while (allClassIter.hasNext()) {
			Collection<Generalization> gensResult = (EcoreUtil
					.getObjectsByType(allClassIter.next().eContents(),
							UMLPackage.Literals.GENERALIZATION));
			Iterator<Generalization> gensIter = gensResult.iterator();
			Generalization gen = null;
			// Проходим по коллекции Generalization и узнаем базовые и
			// производные классы.
			while (gensIter.hasNext()) {
				gen = gensIter.next();
				result.add("extends(cl" + gen.getSpecific().getName() + ",cl"
						+ gen.getGeneral().getName() + ").");
				/*
				 * System.out.println("extends(" + gen.getSpecific().getName() +
				 * "," + gen.getGeneral().getName() + ").");
				 */
			}
		}
		return result;
	}

	private Collection<Class> getAllClass(Object element) {
		if (element instanceof Model) {
			Collection<Class> result = (EcoreUtil.getObjectsByType(
					((Model) element).getPackagedElements(),
					UMLPackage.Literals.CLASS));
			Collection<Package> packages = (EcoreUtil.getObjectsByType(
					((Model) element).getPackagedElements(),
					UMLPackage.Literals.PACKAGE));
			Iterator<Package> packagesIter = packages.iterator();
			while (packagesIter.hasNext()) {
				result.addAll(getAllClass(packagesIter.next()));
			}
			return result;
		} else if (element instanceof Package) {
			Collection<Class> result = (EcoreUtil.getObjectsByType(
					((Package) element).getPackagedElements(),
					UMLPackage.Literals.CLASS));
			Collection<Package> packages = (EcoreUtil.getObjectsByType(
					((Package) element).getPackagedElements(),
					UMLPackage.Literals.PACKAGE));
			Iterator<Package> packagesIter = packages.iterator();
			while (packagesIter.hasNext()) {
				result.addAll(getAllClass(packagesIter.next()));
			}
			return result;
		} else
			return null;
	}
}
